package de.slothsoft.commons.swing.window.phase;

import java.awt.CardLayout;
import java.util.List;

import javax.swing.JPanel;

public class PhaseChangerPanel<P extends Phase<I>, I> extends JPanel implements PhaseChanger<I> {

	private static final long serialVersionUID = 1L;

	private CardLayout cardLayout;
	private final List<P> phases;
	private Phase<I> lastPhase;

	public PhaseChangerPanel(List<P> phases) {
		this.phases = phases;
		createControls();
		initPhase();
	}

	protected void createControls() {
		createPhaseComponent();
	}

	protected void createPhaseComponent() {
		this.cardLayout = new CardLayout();
		setLayout(this.cardLayout);

		int size = this.phases.size();
		for (int i = 0; i < size; i++) {
			Phase<I> phase = this.phases.get(i);
			add(phase.getBaseComponent(), getUniqueString(phase));
		}
	}

	private void initPhase() {
		if (this.phases.size() > 0) {
			changeToPhase(this.phases.get(0));
		}
	}

	@Override
	public void changeToPhase(I id) {
		Phase<I> phase = getPhase(id);
		if (phase == null) {
			throw new UnsupportedOperationException("Could not find phase with id " + id);
		}
		changeToPhase(phase);
	}

	public Phase<I> getPhase(I id) {
		for (Phase<I> phase : this.phases) {
			if (phase.getId().equals(id)) {
				return phase;
			}
		}
		return null;
	}

	public void changeToPhase(Phase<I> phase) {
		if (this.lastPhase != null) {
			this.lastPhase.exitPhase();
		}
		createControls(phase);
		this.cardLayout.show(this, getUniqueString(phase));
		doLayout();
		this.lastPhase = phase;
	}

	public void createControls(I id) {
		Phase<I> phase = getPhase(id);
		if (phase == null) {
			throw new UnsupportedOperationException("Could not find phase with id " + id);
		}
		createControls(phase);
	}

	public void createControls(Phase<I> phase) {
		if (!phase.isInitialized()) {
			phase.createControls();
		}
	}

	protected final String getUniqueString(Phase<I> phase) {
		return getUniqueString(phase.getId());
	}

	protected String getUniqueString(I id) {
		return id == null ? "" : id.toString();
	}

}